/**
  ******************************************************************************
  * @file    common_include.h
  * @author  ashuai0110
  * @version V2.4
  * @date    2024-09-24
  * @brief   公共引用文件(所有组件都需包含此文件)
  *
  ******************************************************************************
  * @attention
  *
  * 版权声明:内容为编者(ashuai0110)原创,使用请注明出处,当然,你也可以不这样做^_^
  * 出处链接:https://gitee.com/ashuai0110/mcu_reuse_development_module.git
  *
  ******************************************************************************
  */

#ifndef __COMMON_INCLUDE_H
#define __COMMON_INCLUDE_H

#ifdef __cplusplus
extern "C" {
#endif

/* 包含头文件-----------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <time.h>

#include "mw_config.h"

/**
 * @addtogroup common
 * @{
 */

/**
 * @addtogroup common_include
 * @{
 */

/* 宏定义---------------------------------------------------------------------*/
/**
 * @defgroup common_include_global_macros common include global macros
 * @{
 */

/**
 * @defgroup generic_error_codes generic error codes
 * @brief    组件通用返回值相关
 * @{
 */
#define MW_RET_OK                                   (0x00u) /*!< 成功,完成 */
#define MW_RET_ERR                                  (0x01u) /*!< 失败,错误 */
#define MW_RET_ING                                  (0x02u) /*!< 进行中 */
#define MW_RET_TIMEOUT                              (0x03u) /*!< 超时 */
#define MW_RET_FULL                                 (0x04u) /*!< 已满,溢出 */
#define MW_RET_ABSENT                               (0x05u) /*!< 不存在,缺少 */
#define MW_RET_LEN_ERR                              (0x06u) /*!< 长度错误 */
#define MW_RET_CHECK_ERR                            (0x07u) /*!< 校验错误 */
#define MW_RET_FRAME_ERR                            (0x08u) /*!< 格式错误 */
#define MW_RET_WRITE_ERR                            (0x09u) /*!< 写入失败 */
#define MW_RET_READ_ERR                             (0x0Au) /*!< 读取失败 */
#define MW_RET_ERASE_ERR                            (0x0Bu) /*!< 擦除失败 */
/**
 * @}
 */

#define MW_UNUSED(x)                                ((void)(x)) /*!< 未使用 */

/**
 * @defgroup print_log_macros print log macros
 * @brief    日志输出相关
 * @{
 */
#if _MW_PRINT_LOG
  #ifndef MW_PRINT_FUNC
    #error "MW_PRINT_FUNC() macros undefined!"
  #endif
#else
#define MW_PRINT_FUNC(fmt, args...)                 MW_UNUSED(0)
#endif
/* DEBUG级别日志输出 */
#define MW_DEBUG_LOG(fmt, args...)                  do { \
                                                    MW_PRINT_FUNC("[%s:%d]DEBUG: "fmt"\r\n",__FILE__,__LINE__,##args); \
                                                    }while(0)
/* WARN级别日志输出 */
#define MW_WARN_LOG(fmt, args...)                   do { \
                                                    MW_PRINT_FUNC("[%s:%d]WARN: "fmt"\r\n",__FILE__,__LINE__,##args); \
                                                    }while(0)
/* ERROR级别日志输出 */
#define MW_ERROR_LOG(fmt, args...)                  do { \
                                                    MW_PRINT_FUNC("[%s:%d]ERROR: "fmt"\r\n",__FILE__,__LINE__,##args); \
                                                    }while(0)
/* 版本信息日志输出 */
#define MW_VER_LOG(n, m, s, p)                      do { \
                                                    MW_PRINT_FUNC("Project: %s, Version: %d.%d.%d, Build Time: %s %s\r\n",n,m,s,p,__DATE__,__TIME__); \
                                                    }while(0)
/**
 * @}
 */

/**
 * @defgroup interrupt_control_macros interrupt control macros
 * @brief    中断控制相关
 * @{
 */
#if _MW_INTERRUPT_CTRL
  #ifndef MW_ENABLE_INT_FUNC
    #error "MW_ENABLE_INT_FUNC() macros undefined!"
  #endif
  #ifndef MW_DISABLE_INT_FUNC
    #error "MW_DISABLE_INT_FUNC() macros undefined!"
  #endif
  #ifndef MW_GET_BASEPRI_FUNC
    #error "MW_GET_BASEPRI_FUNC() macros undefined!"
  #endif
  #ifndef MW_SET_BASEPRI_FUNC
    #error "MW_SET_BASEPRI_FUNC() macros undefined!"
  #endif
/* 开启全局中断 */
#define MW_ENABLE_GLOBAL_INT()                      do { \
                                                    MW_ENABLE_INT_FUNC(); \
                                                    }while(0)
/* 关闭全局中断 */
#define MW_DISABLE_GLOBAL_INT()                     do { \
                                                    MW_DISABLE_INT_FUNC(); \
                                                    }while(0)
/* 临界区上锁 ARM在4位抢占优先级分组中 0x40意为屏蔽抢占优先级号>=4的中断,即屏蔽4~15 */
#define MW_CRITICAL_LOCK()                          { \
                                                    unsigned int lockState; \
                                                    lockState = MW_GET_BASEPRI_FUNC(); \
                                                    MW_SET_BASEPRI_FUNC(0x40u);
/* 临界区解锁 */
#define MW_CRITICAL_UNLOCK()                        MW_SET_BASEPRI_FUNC(lockState); \
                                                    }
#else
#if defined (__MEMORY_H) || defined (__MESSAGE_QUEUE_H) || defined (__RING_BUFFER_H) || defined (__SYNC_METHOD_H) || defined (__FSM_EVENT_QUEUE_H)
#warning "We suggest open the macro _MW_INTERRUPT_CTRL, because the file requires it!"
#endif
#define MW_ENABLE_GLOBAL_INT()                      MW_UNUSED(0)
#define MW_DISABLE_GLOBAL_INT()                     MW_UNUSED(0)
#define MW_CRITICAL_LOCK()                          MW_UNUSED(0)
#define MW_CRITICAL_UNLOCK()                        MW_UNUSED(0)
#endif
/* 原子操作(全局中断) */
#define MW_ATOM_CODE(...)                           do { \
                                                    MW_DISABLE_GLOBAL_INT(); \
                                                    __VA_ARGS__; \
                                                    MW_ENABLE_GLOBAL_INT(); \
                                                    }while(0)
/**
 * @}
 */

/**
 * @defgroup complex_type_macros complex type macros
 * @brief    复杂类型相关操作
 * @{
 */
/* 数组的数量 */
#define MW_ARRAY_NUM(arr)                           (sizeof((arr)) / sizeof((arr)[0]))
/* 结构体清零 */
#define MW_MEM_ZERO_STRUCT(str)                     do { \
                                                    memset((void *)&(str), 0, (sizeof(str))); \
                                                    }while(0)
/**
 * @}
 */

/**
 * @defgroup integer_type_macros integer type macros
 * @brief    整数类型相关操作
 * @{
 */
/* 两者最大值 */
#define MW_MAX(a, b)                                ((a) > (b) ? (a) : (b))
/* 两者最小值 */
#define MW_MIN(a, b)                                ((a) < (b) ? (a) : (b))
/* 向上整数对齐 MW_ALIGN_UP(13,4)=16 */
#define MW_ALIGN_UP(num, align)                     (((num) + (align) - 1) & ~((align) - 1))
/* 向下整数对齐 MW_ALIGN_DOWN(13,4)=12 */
#define MW_ALIGN_DOWN(num, align)                   ((num) & ~((align) - 1))
/* 十进制转换BCD码 MW_DEC2BCD(10)=0x10 */
#define MW_DEC2BCD(val)                             ((((val) / 10u) << 4u) + ((val) % 10u))
/* BCD码转换十进制 MW_BCD2DEC(0x10)=10 */
#define MW_BCD2DEC(val)                             ((((val) >> 4u) * 10u) + ((val) & 0x0Fu))
/**
 * @}
 */

/**
 * @defgroup bit_type_macros bit type macros
 * @brief    位相关操作
 * @{
 */
/* 置位 MW_BIT_SET(0x10,0)=0x11 */
#define MW_BIT_SET(val, bitx)                       ((val) | (1u << (bitx)))
/* 复位 MW_BIT_RESET(0x11,0)=0x10 */
#define MW_BIT_RESET(val, bitx)                     ((val) & ~(1u << (bitx)))
/* 读取位 MW_BIT_READ(0x11,4)=0x10 */
#define MW_BIT_READ(val, bitx)                      ((val) & (1u << (bitx)))
/* 翻转位 MW_BIT_TOGGLE(0x10,0)=0x11 */
#define MW_BIT_TOGGLE(val, bitx)                    ((val) ^ (1u << (bitx)))
/* 替换位 MW_BIT_REPLACE(0xF0,0x03,0)=0xF1 MW_BIT_REPLACE(0x0F,0xFE,0)=0x0E */
#define MW_BIT_REPLACE(sVal, dVal, num)             (((sVal) & (~(1u << (num)))) | ((dVal) & (1u << (num))))
/**
 * @}
 */

/**
 * @defgroup memory_read_write_macros memory read write macros
 * @brief    内存相关操作
 * @{
 */
/* 以内存地址读写1字节 RAM-R/W ROM-R */
#define MW_RW_RAM8(addr)                            (*(char *)(unsigned int)(addr))
/* 以内存地址读写2字节 RAM-R/W ROM-R */
#define MW_RW_RAM16(addr)                           (*(short *)(unsigned int)(addr))
/* 以内存地址读写4字节 RAM-R/W ROM-R */
#define MW_RW_RAM32(addr)                           (*(int *)(unsigned int)(addr))
/**
 * @}
 */

/**
 * @defgroup maximum_base_type_macros maximum value of base type
 * @brief    基础类型的最大值
 * @{
 */
#ifndef MW_UINT8_MAX
  #define MW_UINT8_MAX                              (0xFFu)
#endif
#ifndef MW_UINT16_MAX
  #define MW_UINT16_MAX                             (0xFFFFu)
#endif
#ifndef MW_UINT32_MAX
  #define MW_UINT32_MAX                             (0xFFFFFFFFu)
#endif
/**
 * @}
 */

/**
 * @defgroup parameter_check_macros parameter check macros
 * @brief    参数检查相关
 * @{
 */
#if _MW_ASSERT_PARAM
/* 参数检查 */
#define MW_ASSERT_PARAM(x)                          ((x) ? (void)0u : mw_assert_failed((uint8_t *)__FILE__, __LINE__))
#else
#define MW_ASSERT_PARAM(x)                          MW_UNUSED(0)
#endif
/* 指针有效性检查 */
#define IS_VALID_POINTER(p)                         ((p) != NULL)
/**
 * @}
 */

/**
 * @defgroup weak_function_define weak function define
 * @brief    弱函数定义
 * @{
 */
#if defined (__GNUC__) && !defined (__CC_ARM) /*!< GNU Compiler */
  #ifndef __weak
    #define __weak                                  __attribute__((weak))
  #endif
#elif defined (__ICCARM__) /*!< IAR Compiler */
  #ifndef __weak
    #define __weak                                  __weak
  #endif
#elif defined (__CC_ARM) /*!< ARM Compiler */
  #ifndef __weak
    #define __weak                                  __attribute__((weak))
  #endif
#else
  #error  "unsupported compiler!"
#endif
/**
 * @}
 */

/**
 * @}
 */

/* 类型定义-------------------------------------------------------------------*/
/**
 * @defgroup common_include_global_types common include global types
 * @{
 */

/**
  * @brief  常用普通函数类型
  *
  * @param  None
  *
  * @retval None
  */
typedef void (* mw_normal_fn_t)(void);

/**
  * @brief  常用读写数据类型
  *
  * @param  data : 写入数据的存储区 / 读取数据的存储区
  *
  * @param  len  : 写入的数据大小 / 读取的数据大小 byte
  *
  * @retval 返回实际写入的数据大小 / 返回实际读取的数据大小 byte
  */
typedef uint32_t (* mw_rw_fn_t)(void *data, uint32_t len);

/**
  * @brief  组件时间 structure definition
  */
#if _MW_TIME_STAMP
typedef struct mw_time {
    uint16_t year;  /*!< 年 20xx */
    uint8_t month;  /*!< 月 1~12 */
    uint8_t day;    /*!< 日 1~31 */
    uint8_t week;   /*!< 周 1~7 */
    uint8_t hour;   /*!< 时 0~23 */
    uint8_t minute; /*!< 分 0~59 */
    uint8_t second; /*!< 秒 0~59 */
} mw_time_t;
#endif

/**
 * @}
 */

/* 全局变量-------------------------------------------------------------------*/

/* 函数原型-------------------------------------------------------------------*/
/**
 * @addtogroup common_include_global_functions
 * @{
 */

void mw_tick_inc(uint32_t ticks);
uint32_t mw_tick_get(void);

/* 弱定义函数 */
void mw_delay_ms(uint32_t ms);
void mw_delay_us(uint32_t us);

#if _MW_ASSERT_PARAM
/* 弱定义函数 */
void mw_assert_failed(uint8_t *file, uint32_t line);
#endif

#if _MW_TIME_STAMP
void mw_time_stamp_init(uint32_t baseTime);
void mw_time_stamp_1s(void);
uint32_t mw_time_stamp_get(void);

uint32_t mw_time_stamp_conv(mw_time_t mwTime);
void mw_time_std_conv(mw_time_t *_time, uint32_t timeStamp);
void mw_time_sntp_conv(mw_time_t *_time, char *sntpTime);
#endif

/**
 * @}
 */

/**
 * @}
 */

/**
 * @}
 */

#ifdef __cplusplus
}
#endif

#endif /* common_include.h */
